import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;

import edu.ucla.cs.typecast.net.NetUtil;


public class MulticastSender {
    public static void main(String[] args) { 
        System.setProperty("java.net.preferIPv4Stack","true"); 
        byte[] packet = new byte[1024]; 
        int seqno = 0; 
        try {             
            Options options = new Options(args); 
            String group = options.getOption("-group"); 
            InetAddress grpAddr = InetAddress.getByName(group); 
            int port = Integer.parseInt(options.getOption("-port"));            
            int interval = 5000; 
            if (options.hasOption("-interval")) { 
                interval = 1000 * Integer.parseInt(options.getOption("-interval")); 
            }
            
            String filter = options.getParameter(0); 
            InetSocketAddress addr = new InetSocketAddress(NetUtil.getLocalHost(), 0);              
            System.out.println("Local IP address is " + NetUtil.getLocalHost().getHostAddress()); 
            MulticastSocket socket = new MulticastSocket(addr);             
            System.out.println("Local IP address is " + socket.getLocalAddress()); 
            socket.setLoopbackMode(false); 
            socket.setTimeToLive(16); 
            socket.setNetworkInterface(NetworkInterface.getByName("eth1")); 
            socket.joinGroup(grpAddr); 

            BloomFilter bloomFilter = new BloomFilter(filter); 
            System.arraycopy(bloomFilter.getValue(), 0, packet, 0, BloomFilter.SIZE); 
            while(true) { 
                toByte(seqno, packet, BloomFilter.SIZE); 
                DatagramPacket pack = new DatagramPacket(packet, packet.length, grpAddr, port); 
                socket.send(pack);
                System.out.println("Sending packet to group " + pack.getAddress() + " port " + pack.getPort() +  " (seqno=" + seqno +")  filter=" + bloomFilter.toString()); 
                Thread.sleep(interval); 
                seqno++; 
            }
        } catch(Throwable t) { 
            t.printStackTrace(); 
        }
    }
    
    static void toByte(int number, byte[] buf, int start) { 
        buf[start] = (byte)(number >> 24 & 0xFF); 
        buf[start+1] = (byte)(number >> 16 & 0xFF); 
        buf[start+2] = (byte)(number >> 8 & 0xFF); 
        buf[start+3] = (byte) (number & 0xFF); 
    }
}
